import { Injectable, ConflictException, UnauthorizedException, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcryptjs';
import { User } from '../common/entities/user.entity';
import { RegisterDto } from './dto/register.dto';
import { LoginDto } from './dto/login.dto';
import { SendCaptchaDto } from './dto/send-captcha.dto';
import { AppLoggerService } from '../../shared/services/logger.service';

@Injectable()
export class AuthService {
  private readonly logger = new AppLoggerService('AuthService');

  constructor(
    @InjectRepository(User)
    private userRepository: Repository<User>,
    private jwtService: JwtService,
  ) {}

  // 验证码存储（实际项目中应该使用Redis）
  private captchaStore = new Map<string, { code: string; expireTime: number }>();

  async register(registerDto: RegisterDto) {
    const { username, phone, password, captcha } = registerDto;
    const startTime = Date.now();

    this.logger.info(`开始用户注册流程: ${username}`, 'AuthService');
    this.logger.debug(`注册参数: ${JSON.stringify({ username, phone, captcha: '***' })}`, 'AuthService');

    // 开发环境跳过验证码验证
    this.logger.debug(`跳过验证码验证: ${phone} - ${captcha}`, 'AuthService');

    try {
      // 检查用户名是否已存在
      this.logger.debug(`检查用户名是否已存在: ${username}`, 'AuthService');
      const existingUserByUsername = await this.userRepository.findOne({
        where: { username }
      });
      if (existingUserByUsername) {
        this.logger.warning(`用户名已存在: ${username}`, 'AuthService');
        throw new ConflictException('用户名已存在');
      }

      // 检查手机号是否已存在
      this.logger.debug(`检查手机号是否已存在: ${phone}`, 'AuthService');
      const existingUserByPhone = await this.userRepository.findOne({
        where: { phone }
      });
      if (existingUserByPhone) {
        this.logger.warning(`手机号已存在: ${phone}`, 'AuthService');
        throw new ConflictException('手机号已存在');
      }

      // 加密密码
      this.logger.debug('开始密码加密', 'AuthService');
      const hashedPassword = await bcrypt.hash(password, 10);
      this.logger.debug('密码加密完成', 'AuthService');

      // 创建用户
      this.logger.debug('创建用户实体', 'AuthService');
      const user = this.userRepository.create({
        username,
        phone,
        password: hashedPassword,
      });

      this.logger.debug('保存用户到数据库', 'AuthService');
      const savedUser = await this.userRepository.save(user);
      this.logger.success(`用户注册成功: ${username} (ID: ${savedUser.id})`, 'AuthService');

      // 删除验证码
      this.captchaStore.delete(phone);
      this.logger.debug(`删除验证码: ${phone}`, 'AuthService');

      // 返回用户信息（不包含密码）
      const { password: _, ...userWithoutPassword } = savedUser;
      const duration = Date.now() - startTime;
      this.logger.performance(`用户注册`, duration, 'AuthService');
      
      return userWithoutPassword;
    } catch (error) {
      const duration = Date.now() - startTime;
      this.logger.error(`用户注册失败: ${error.message}`, error.stack, 'AuthService');
      this.logger.performance(`用户注册失败`, duration, 'AuthService');
      throw error;
    }
  }

  async login(loginDto: LoginDto) {
    const { username, password } = loginDto;
    const startTime = Date.now();

    this.logger.authAttempt(username);
    this.logger.info(`开始用户登录流程: ${username}`, 'AuthService');

    try {
      // 查找用户
      this.logger.debug(`查找用户: ${username}`, 'AuthService');
      const user = await this.userRepository.findOne({
        where: { username }
      });

      if (!user) {
        this.logger.authFailure(username, '用户不存在');
        throw new UnauthorizedException('用户名或密码错误');
      }

      this.logger.debug(`找到用户: ${username} (ID: ${user.id})`, 'AuthService');

      // 检查用户状态
      if (user.status === 0) {
        this.logger.authFailure(username, '用户已被禁用');
        throw new UnauthorizedException('用户已被禁用');
      }

      this.logger.debug('用户状态正常', 'AuthService');

      // 验证密码
      this.logger.debug('开始密码验证', 'AuthService');
      const isPasswordValid = await bcrypt.compare(password, user.password);
      if (!isPasswordValid) {
        this.logger.authFailure(username, '密码错误');
        throw new UnauthorizedException('用户名或密码错误');
      }

      this.logger.debug('密码验证成功', 'AuthService');

      // 生成JWT token
      this.logger.debug('生成JWT Token', 'AuthService');
      const payload = { sub: user.id, username: user.username };
      const token = this.jwtService.sign(payload);
      this.logger.debug('JWT Token生成完成', 'AuthService');

      // 返回用户信息和token
      const { password: _, ...userWithoutPassword } = user;
      const duration = Date.now() - startTime;
      
      this.logger.authSuccess(username, user.id);
      this.logger.performance(`用户登录`, duration, 'AuthService');
      
      return {
        token,
        user: userWithoutPassword,
      };
    } catch (error) {
      const duration = Date.now() - startTime;
      this.logger.error(`用户登录失败: ${error.message}`, error.stack, 'AuthService');
      this.logger.performance(`用户登录失败`, duration, 'AuthService');
      throw error;
    }
  }

  async sendCaptcha(sendCaptchaDto: SendCaptchaDto) {
    const { phone, type } = sendCaptchaDto;
    const startTime = Date.now();

    this.logger.info(`开始发送验证码: ${phone} (类型: ${type})`, 'AuthService');

    try {
      // 生成6位数字验证码
      this.logger.debug('生成验证码', 'AuthService');
      const code = Math.floor(100000 + Math.random() * 900000).toString();
      const expireTime = Date.now() + 5 * 60 * 1000; // 5分钟后过期

      // 存储验证码
      this.logger.debug(`存储验证码: ${phone}`, 'AuthService');
      this.captchaStore.set(phone, { code, expireTime });

      // 这里应该调用短信服务发送验证码
      // 实际项目中需要集成短信服务商API
      this.logger.info(`发送验证码到 ${phone}: ${code} (类型: ${type})`, 'AuthService');

      const duration = Date.now() - startTime;
      this.logger.performance(`发送验证码`, duration, 'AuthService');

      return {
        expireTime: 300, // 5分钟
      };
    } catch (error) {
      const duration = Date.now() - startTime;
      this.logger.error(`发送验证码失败: ${error.message}`, error.stack, 'AuthService');
      this.logger.performance(`发送验证码失败`, duration, 'AuthService');
      throw error;
    }
  }

  private async validateCaptcha(phone: string, code: string, type: string) {
    this.logger.debug(`验证验证码: ${phone} (类型: ${type})`, 'AuthService');
    
    // 开发环境跳过验证码验证
    if (process.env.NODE_ENV !== 'production') {
      this.logger.debug(`🔓 开发环境跳过验证码验证: ${phone} - ${code}`, 'AuthService');
      return;
    }

    const captchaData = this.captchaStore.get(phone);
    
    if (!captchaData) {
      this.logger.warning(`验证码不存在: ${phone}`, 'AuthService');
      throw new BadRequestException('验证码不存在');
    }

    if (Date.now() > captchaData.expireTime) {
      this.logger.warning(`验证码已过期: ${phone}`, 'AuthService');
      this.captchaStore.delete(phone);
      throw new BadRequestException('验证码已过期');
    }

    if (captchaData.code !== code) {
      this.logger.warning(`验证码错误: ${phone}`, 'AuthService');
      throw new BadRequestException('验证码错误');
    }

    this.logger.debug(`验证码验证成功: ${phone}`, 'AuthService');
  }

  async validateUser(userId: number): Promise<User> {
    const user = await this.userRepository.findOne({
      where: { id: userId }
    });

    if (!user) {
      throw new UnauthorizedException('用户不存在');
    }

    if (user.status === 0) {
      throw new UnauthorizedException('用户已被禁用');
    }

    return user;
  }
}
